#!/usr/bin/env python3
"""
Flowable 流程批量部署脚本
用于批量部署所有 BPMN 流程文件
"""

import os
import sys
import requests
from requests.auth import HTTPBasicAuth
from pathlib import Path
from typing import List, Tuple

# 配置
# 注意：如果 Flowable UI 和 REST API 在同一端口，使用 8080
# 如果分开部署，REST API 通常在 8081
FLOWABLE_URL = os.getenv("FLOWABLE_URL", "http://localhost:8081/flowable-rest")
FLOWABLE_USER = os.getenv("FLOWABLE_USER", "admin")
FLOWABLE_PASS = os.getenv("FLOWABLE_PASS", "test")

# 流程文件目录
PROCESSES_DIR = Path(__file__).parent / "processes"


class FlowableDeployer:
    """Flowable 流程部署器"""
    
    def __init__(self, base_url: str, username: str, password: str):
        self.base_url = base_url.rstrip('/')
        self.auth = HTTPBasicAuth(username, password)
        self.session = requests.Session()
        self.session.auth = self.auth
    
    def check_service_health(self) -> bool:
        """检查 Flowable 服务是否可用"""
        try:
            url = f"{self.base_url}/service/management/engine"
            response = self.session.get(url, timeout=5)
            return response.status_code == 200
        except Exception as e:
            print(f"❌ 无法连接到 Flowable 服务: {e}")
            return False
    
    def deploy_process(self, bpmn_file: Path) -> Tuple[bool, str]:
        """部署单个流程文件"""
        try:
            url = f"{self.base_url}/service/repository/deployments"
            
            with open(bpmn_file, 'rb') as f:
                files = {
                    'file': (bpmn_file.name, f, 'application/xml')
                }
                response = self.session.post(url, files=files, timeout=30)
            
            if response.status_code == 201:
                deployment_info = response.json()
                deployment_id = deployment_info.get('id', 'unknown')
                return True, f"部署成功 (ID: {deployment_id})"
            else:
                error_msg = response.text[:200] if response.text else "未知错误"
                return False, f"HTTP {response.status_code}: {error_msg}"
        
        except FileNotFoundError:
            return False, "文件不存在"
        except Exception as e:
            return False, str(e)
    
    def deploy_all_processes(self) -> Tuple[int, int]:
        """部署所有流程文件"""
        bpmn_files = list(PROCESSES_DIR.glob("*.bpmn20.xml"))
        
        if not bpmn_files:
            print(f"❌ 在 {PROCESSES_DIR} 目录下未找到 BPMN 文件")
            return 0, 0
        
        print(f"\n找到 {len(bpmn_files)} 个流程文件，开始部署...\n")
        
        deployed = 0
        failed = 0
        
        for bpmn_file in sorted(bpmn_files):
            filename = bpmn_file.name
            print(f"部署: {filename}...", end=" ")
            
            success, message = self.deploy_process(bpmn_file)
            
            if success:
                print(f"✅ {message}")
                deployed += 1
            else:
                print(f"❌ {message}")
                failed += 1
        
        return deployed, failed


def main():
    """主函数"""
    print("=" * 60)
    print("Flowable 流程批量部署脚本")
    print("=" * 60)
    print(f"Flowable URL: {FLOWABLE_URL}")
    print(f"用户名: {FLOWABLE_USER}")
    print(f"流程目录: {PROCESSES_DIR}")
    print("=" * 60)
    
    deployer = FlowableDeployer(FLOWABLE_URL, FLOWABLE_USER, FLOWABLE_PASS)
    
    # 检查服务健康状态
    print("\n检查 Flowable 服务状态...")
    if not deployer.check_service_health():
        print("\n❌ Flowable 服务不可用，请确保服务已启动")
        print(f"   检查地址: {FLOWABLE_URL}")
        sys.exit(1)
    
    print("✅ Flowable 服务连接成功")
    
    # 部署所有流程
    deployed, failed = deployer.deploy_all_processes()
    
    # 打印结果
    print("\n" + "=" * 60)
    print("部署完成")
    print("=" * 60)
    print(f"成功: {deployed}")
    print(f"失败: {failed}")
    print("=" * 60)
    
    if failed > 0:
        print("\n⚠️  部分流程部署失败，请检查错误信息")
        sys.exit(1)
    else:
        print("\n✅ 所有流程部署成功！")
        sys.exit(0)


if __name__ == "__main__":
    main()

